from django.db import models
from datetime import datetime
from codeflow import settings
from codeflow.core.models import ScmUser
import pysvn

def get_scm_client():
    c = pysvn.Client()
    def get_login(self, realm, username, may_save):
        if not hasattr(settings, 'CODEFLOW_SCM_USER'):
            return False, None, None, None
        else:
            return True, settings.CODEFLOW_SCM_USER, \
                   settings.CODEFLOW_SCM_PASSWORD, False
    c.callback_get_login = get_login
    return c

def _head_revision():
    return pysvn.Revision(pysvn.opt_revision_kind.head)

def sync_changesets():
    "Creates Changeset instances for every changeset found on the SCM"
    scm = get_scm_client()
    log = scm.log(settings.CODEFLOW_SCM_REPO,
                  revision_start=_head_revision(),
                  revision_end=_head_revision())
    last_rev_num = log[0]['revision'].number # TODO: Check if info is OK
    for rev_num in xrange(1, last_rev_num + 1):
        Changeset.objects.get_or_create(scm_id=str(rev_num))
    
    
    

class Changeset(models.Model):
    scm_id = models.CharField("SCM Id", maxlength=200, unique=True)
    message = models.TextField("Message")
    scm_user = models.ForeignKey(ScmUser)
    date = models.DateTimeField("Date")
    def _get_rev(self):
        return pysvn.Revision(pysvn.opt_revision_kind.number,
                              self.scm_id)
    def _get_previous_rev(self):
        if int(self.scm_id) >= 1:
            return pysvn.Revision(pysvn.opt_revision_kind.number,
                                  int(self.scm_id) - 1)
        else:
            return None
    def _get_log(self):
        scm = get_scm_client()
        msgs = scm.log(settings.CODEFLOW_SCM_REPO,
                       revision_start=self._get_rev(),
                       revision_end=self._get_rev(),
                       discover_changed_paths=True)
        assert len(msgs) == 1, "Should have one log message per changeset"
        return msgs[0]
    def save(self):
        log = self._get_log()
        scm_user, created = ScmUser.objects.get_or_create(
            scm_user_name=log['author'])
        self.message = log['message']
        self.scm_user = scm_user
        self.date = datetime.fromtimestamp(log['date'])
        super(Changeset, self).save()
    def changed_paths(self):
        "Returns a sequence of path names changed in this changeset"
        for changed_path in self._get_log()['changed_paths']:
            yield changed_path['path']
    def __str__(self):
        return "Changeset %s: %s" % (self.scm_id, self.message)
    class Admin:
        pass
